<template>
  <el-container>
    <el-header height="68" style="padding: 0;">
      <Header/>
    </el-header>
    <el-container style="max-height: 900px">
      <el-aside width="300px">
        <div class="nodeBox" @contextmenu.prevent="openMenu($event)" @click="handleLeftclick">
          <div class="nodeTerminal" v-for="(item, index) in terminalList" :key="index" :id="item.id">
            {{ item.name }}
          </div>
        </div>
        <el-card class="box-card" ref="card" v-show="menuVisible">
          <div class="add" @click="bindEvent"><i class="el-icon-circle-plus-outline"></i>绑定终端</div>
          <div class="delete" @click="relieveEvent"><i class="el-icon-remove-outline"></i>解除终端</div>
        </el-card>
      </el-aside>
      <el-main style="padding: 0;">
        <div ref="imageContainer" style="position: relative; display: inline-block; width: 100%; max-width: 100%;">
          <el-image
              :src="mapBase64"
              alt="Sample Image"
              @click="getRelativeCoords"
              style="width: 100%; height: auto;"
          />
          <!-- 用于显示标记的 SVG 图标和文本 -->
          <div
              v-for="(marker, index) in pointList"
              :key="index"
              :style="getMarkerStyle(marker.coordX, marker.coordY)"
              style="position: absolute; text-align: center; width: 40px; height: 40px;"
          >
            <!-- 显示标记名 -->
            <span
                style="position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); white-space: nowrap; font-size: 12px; color: #C63520;">
                  {{ marker.name }}
            </span>
            <!-- SVG 图标 -->
            <svg
                class="icon"
                viewBox="0 0 1024 1024"
                xmlns="http://www.w3.org/2000/svg"
                width="40"
                height="40"
            >
              <path
                  d="M501.097 819.37l11.466 11.807 11.469-11.807c0.717-0.717 71.434-73.667 141.172-163.211 95.188-122.172 143.47-216.060 143.47-279.039 0-73.71-31.012-142.91-87.29-194.842-55.839-51.571-130.027-79.971-208.822-79.971-78.814 0-152.979 28.399-208.82 79.97-56.299 51.933-87.291 121.133-87.291 194.842 0 62.979 48.282 156.867 143.468 279.039 69.741 89.545 140.458 162.495 141.177 163.212zM512.561 277.126c56.38 0 102.268 46.546 102.268 103.743 0 57.235-45.888 103.78-102.268 103.78-56.377 0-102.266-46.546-102.266-103.78 0-57.197 45.889-103.743 102.266-103.743zM686.902 753.717l-25.627 25.607c16.793 10.81 26.722 22.895 26.722 34.543 0 32.986-76.142 69.837-178.068 69.837-101.927 0-178.069-36.852-178.069-69.837 0-12.724 11.548-25.967 31.33-37.534l-23.214-27.359c-27.142 17.628-43.077 39.965-43.077 64.853 0 60.028 91.557 105.298 213.030 105.298 121.472 0 213.009-45.231 213.009-105.298-0.038-22.656-13.162-43.278-36.035-60.109z"
                  fill="#d81e06"
              ></path>
            </svg>
          </div>
        </div>
      </el-main>
    </el-container>
    <el-footer height="68" style="padding: 0;">
      <Footer/>
    </el-footer>
  </el-container>
</template>

<script>
import {get_map_base64, terminal_all_site, terminal_update_info} from "@/utils/request/api";
import Header from "@/views/common/Header.vue";
import Footer from "@/views/common/Footer.vue";

export default {
  name: "MapImg",
  components: {Footer, Header},
  data() {
    return {
      // 右击显示卡片列表
      menuVisible: false,
      // 是否开启点击标点功能
      clickPoint: false,
      markers: [], // 存储所有标记的比例坐标
      mapBase64: '', // 地图图片的 base64 数据
      // 终端集合
      terminalList: [],
      // 每次右击保存终端id和name
      menuObj: {},
      pointList: [],
    };
  },
  methods: {
    // 鼠标左击事件
    handleLeftclick() {
      this.foo();
    },
    //  取消鼠标监听事件 菜单栏
    foo() {
      this.menuVisible = false; //  要及时关掉监听，不关掉的是一个坑，不信你试试，虽然前台显示的时候没有啥毛病，加一个alert你就知道了
      document.removeEventListener("click", this.foo);
    },
    // 鼠标右击事件
    openMenu(e) {
      this.menuVisible = true;
      document.addEventListener("click", this.foo);
      this.$refs.card.$el.style.left = e.clientX + 20 + "px";
      this.$refs.card.$el.style.top = e.clientY - 55 + "px";
      this.menuObj.id = e.target.id;
      this.menuObj.name = e.target.innerText;
    },
    // 绑定事件
    bindEvent() {
      const b = this.pointList.some((item) => {
        return Number(item.id) === Number(this.menuObj.id);
      });
      if (b) {
        this.$message.warning("已经绑定过，请先移除");
        return;
      }
      this.clickPoint = true;
    },
    // 解绑事件
    relieveEvent() {
      const b = this.pointList.some((item) => {
        return Number(item.id) === Number(this.menuObj.id);
      });
      if (!b) {
        this.$message.warning("当前设备尚未绑定");
        return;
      }
      this.pointList = this.pointList.filter(item => Number(item.id) !== Number(this.menuObj.id));
      terminal_update_info({id: this.menuObj.id, mapCoord: ','}).then(res => {
        if (res.code === 200) {
          this.$message.success("终端坐标解绑成功");
        }
      })
    },

    async getMapBase64() {
      await get_map_base64()
          .then((res) => {
            if (res.code === 200) {
              this.mapBase64 = 'data:image/png;base64,' + res.data;
            } else {
              this.$msg.error("地图获取失败！");
            }
          });
    },
    // 获取所有终端
    async getTerminal() {
      await terminal_all_site().then((res) => {
        if (res.code === 200) {
          this.terminalList = res.data;
          this.pointList = [];
          this.terminalList.forEach((item) => {
            if (item.mapCoord && item.mapCoord !== ",") {
              this.pointList.push({
                id: item.id,
                name: item.name,
                coordX: item.mapCoord.split(",")[0],
                coordY: item.mapCoord.split(",")[1],
              });
            }
          });
        } else {
          this.$msg.error("终端获取失败！");
        }
      });
    },
    getRelativeCoords(event) {
      if (!this.clickPoint) {
        return;
      }
      // 获取图片容器的 DOM 元素
      const imgContainer = this.$refs.imageContainer;
      const imgRect = imgContainer.getBoundingClientRect();

      // 计算点击位置相对于图片的比例坐标
      const relativeX = event.clientX - imgRect.left;
      const relativeY = event.clientY - imgRect.top;
      const xRatio = relativeX / imgRect.width;
      const yRatio = relativeY / imgRect.height;
      const saveXRatio = Math.ceil(xRatio * 100000);
      const saveYRatio = Math.ceil(yRatio * 100000);

      // 将标记的比例坐标添加到 markers 数组中
      this.pointList.push({
        id: this.menuObj.id,
        name: this.menuObj.name,
        coordX: saveXRatio,
        coordY: saveYRatio,
      });
      this.clickPoint = false;
      // 输出比例坐标，便于调试
      terminal_update_info({id: this.menuObj.id, mapCoord: `${saveXRatio},${saveYRatio}`}).then(res => {
        if (res.code === 200) {
          this.$message.success("终端坐标修改成功");
        }
      })
    },
    // 根据比例坐标计算样式
    getMarkerStyle(xRatio, yRatio) {
      const imgContainer = this.$refs.imageContainer;
      if (!imgContainer) return {};

      const imgRect = imgContainer.getBoundingClientRect();

      return {
        position: 'absolute',
        left: `${xRatio / 100000 * imgRect.width - 20}px`, // 减去 20，确保中心对齐
        top: `${yRatio / 100000 * imgRect.height - 20}px`, // 减去 20，确保中心对齐
        width: '40px', // SVG 图标宽度
        height: '40px', // SVG 图标高度
      };
    }
  },
  async mounted() {
    await this.getMapBase64();
    await this.getTerminal();
  },
};
</script>

<style scoped lang="less">
.el-image {
  width: 100%; /* 宽度根据浏览器宽度自适应 */
  height: auto; /* 高度根据宽度等比例缩放 */
  max-width: 100%; /* 防止超出容器的宽度 */
}

.image-container {
  width: 100%; /* 容器宽度为100% */
  max-width: 100%; /* 单位屏幕宽度 */
  position: relative; /* 确保标记依附在图片上 */
}

.icon {
  position: absolute;
  z-index: 9;
  transform-origin: center;
}

.nodeBox {
  width: 100%;
  height: 100%;
  background: #fff;
  overflow-y: scroll;

  .nodeTerminal {
    width: 85%;
    height: 58px;
    line-height: 58px;
    text-align: center;
    background: #eee;
    margin: 0 auto 12px;
    box-sizing: border-box;
  }

  .nodeTerminal:last-child {
    margin-bottom: 0;
  }

  .nodeTerminal:first-child {
    margin-top: 12px;
  }

  .nodeTerminal:hover {
    cursor: pointer;
  }
}

.box-card {
  width: 150px;
  position: absolute;
  z-index: 1;

  .add {
    cursor: pointer;
    margin-top: 10px;
  }

  .delete {
    margin: 10px 0;
    cursor: pointer;
  }
}

/deep/ .el-card__body {
  padding: 10px !important;

  > div {
    padding-bottom: 10px;
    border-bottom: 1px solid #ccc;

    &:hover {
      color: #a8d55f;
    }
  }
}
</style>